/*
 * TcpClient.cpp
 *
 *  Created on: 2016年5月13日
 *      Author: terry
 */

#include "TcpClient.h"

namespace av
{

TcpClient::TcpClient():
		m_ip(),
		m_port(),
		m_sendBufferSize(1024*1024),
		m_sentSize()
{
}

TcpClient::~TcpClient()
{
	disconnect();
}

bool TcpClient::connect(const std::string& ip, int port)
{
	m_ip = ip;
	m_port = port;

	return doConnect(m_ip, m_port);

}

void TcpClient::disconnect()
{
	m_socket.close();
}

bool TcpClient::isConnected()
{
	return m_socket.isOpen();
}

comn::Socket& TcpClient::getSocket()
{
	return m_socket;
}

bool TcpClient::write(ByteBufferPtr& buffer)
{
	int ret = m_socket.checkWriteAndException(0);
	if (ret < 0)
	{
		if (!doConnect(m_ip, m_port))
		{
			return false;
		}
	}

	if (flushBuffer())
	{
		m_buffer = buffer;
		m_sentSize = 0;
		return flushBuffer();
	}
	else
	{
		/// 丢弃该块
		return false;
	}
}

bool TcpClient::equals(const std::string& ip, uint16_t port) const
{
	return (m_ip == ip) && (m_port == port);
}

void TcpClient::setSendBuffer(int size)
{
	m_sendBufferSize = size;
}

bool TcpClient::doConnect(const std::string& ip, uint16_t port)
{
	m_socket.close();

	m_socket.open(SOCK_STREAM);
	m_socket.setNonblock(true);
	m_socket.setReuse();
	m_socket.setSendBufferSize(m_sendBufferSize);

	m_socket.connect(ip.c_str(), port);

	return m_socket.checkConnect(10) > 0;
}

bool TcpClient::flushBuffer()
{
	if (!m_buffer)
	{
		return true;
	}

	if (m_sentSize >= (int)m_buffer->size())
	{
		m_sentSize = 0;
		m_buffer.reset();
		return true;
	}

	uint8_t* data = m_buffer->data();
	size_t size = m_buffer->size();

	data += m_sentSize;
	size -= m_sentSize;

	int ret = m_socket.send((char*)data, size, 0);
	if (ret <= 0)
	{
		return false;
	}

	m_sentSize += ret;

	if (m_sentSize >= (int)m_buffer->size())
	{
		m_sentSize = 0;
		m_buffer.reset();
		return true;
	}
	return false;
}



} /* namespace av */
